package com.feri.fs.provider.core;

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;

/**
 * @ClassName ZipUtils
 * @Description TODO
 * @Author xing
 * @Date 2021/11/9 14:27
 * @Version 1.0
 */
public class ZipUtils {
    /**
     * 生成压缩文件
     * @param dir 要要是文件夹名称
     * @param os 压缩结果的输出流*/
    public static void createZip(String dir, OutputStream os){
        ZipOutputStream zos = null ;
        try {
            zos = new ZipOutputStream(os);
            File file = new File(dir);
            //递归压缩
            compressZip(file,zos,file.getName());
            zos.closeEntry();
            zos.close();
        } catch (Exception e) {
            throw new RuntimeException("zip error from ZipUtils",e);
        }
    }
    /**
     * 实现递归压缩*/
    private static void compressZip(File file,ZipOutputStream zos,String fname)throws IOException {
        byte[] buf = new byte[2048];
        //验证是否为文件
        if(file.isFile()){
            // 向zip输出流中添加一个zip实体，构造器中fname为zip实体的文件的名字
            System.err.println(fname);
            zos.putNextEntry(new ZipEntry(fname));
            // copy文件到zip输出流中
            int len;
            FileInputStream in = new FileInputStream(file);
            while ((len = in.read(buf)) != -1){
                zos.write(buf, 0, len);
            }
            //关闭
            zos.closeEntry();
            in.close();
        } else {
            //文件夹，需要获取子文件
            File[] listFiles = file.listFiles();
            //验证是否有子内容，如果没有，自己参加压缩
            if(listFiles == null || listFiles.length == 0){
                // 需要保留原来的文件结构时,需要对空文件夹进行处理
                zos.putNextEntry(new ZipEntry(fname+"/"));
                // 没有文件，不需要文件的copy
                zos.closeEntry();
            }else {
                //存在子内容，遍历，递归
                for (File f : listFiles) {
                    // 注意：file.getName()前面需要带上父文件夹的名字加一斜杠,
                    // 不然最后压缩包中就不能保留原来的文件结构,即：所有文件都跑到压缩包根目录下了
                    compressZip(f, zos, fname + "/"+f.getName() );
                }
            }
        }
    }
}
